const {
  ApolloClient,
  createHttpLink,
  InMemoryCache,
  gql,
} = require('@apollo/client/core')
const { setContext } = require('@apollo/client/link/context')
const { onError } = require('@apollo/client/link/error')
const jwtDecode = require('jwt-decode')
const BASE_URL = 'http://127.0.0.1:5001/'
let _token = null
const tokens = {}
const authLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      authorization: _token ? `Bearer ${_token}` : '',
    },
  }
})
const resetToken = onError(
  ({ graphQLErrors, networkError, operation, forward }) => {
    if (graphQLErrors) {
      for (let err of graphQLErrors) {
        if (err.extensions.code === 'UNAUTHENTICATED') {
          history.push('/login')
        }
      }
    }
  }
)
const httpLink = createHttpLink({
  uri: BASE_URL,
})
const client = new ApolloClient({
  // uri: 'http://127.0.0.1:5001/',
  cache: new InMemoryCache(),
  link: resetToken.concat(authLink).concat(httpLink),
  defaultOptions: {
    watchQuery: {
      fetchPolicy: 'no-cache',
      errorPolicy: 'ignore',
    },
    query: {
      fetchPolicy: 'no-cache',
      errorPolicy: 'all',
    },
  },
})

const MUTATION_LOGIN = gql`
  mutation Login($username: String!, $password: String!) {
    login(username: $username, password: $password) {
      token
    }
  }
`
const GET_RESERVATION = gql`
  query GetReservation {
    getReservation {
      id
      arrivalDate
      arrivalTime
      tableSize
      name
      phone
      status
      createdAt
    }
  }
`
const getUser = async (username, password) => {
  try {
    const res = await client.mutate({
      mutation: MUTATION_LOGIN,
      variables: {
        username,
        password,
      },
    })
    const {
      data: {
        login: { token },
      },
    } = res
    const user = jwtDecode(token)
    tokens[username] = token
    return user
  } catch (error) {
    throw error
  }
}
const getReservations = async (username) => {
  try {
    _token = tokens[username]
    const res = await client.query({
      query: GET_RESERVATION,
    })
    const {
      data: { getReservation },
    } = res
    return getReservation
  } catch (error) {
    throw error
  }
}
module.exports = { getUser, getReservations }
